/// -----------------------------------------------------------------------------------------------------------
/// Module      :  QueueStorageAdapterBindingElementExtensionElement.cs
/// Description :  This class is provided to surface Adapter as a binding element, so that it 
///                can be used within a user-defined WCF "Custom Binding".
///                In configuration file, it is defined under
///                <system.serviceModel>
///                  <extensions>
///                     <bindingElementExtensions>
///                         <add name="{name}" type="{this}, {assembly}"/>
///                     </bindingElementExtensions>
///                  </extensions>
///                </system.serviceModel>
/// -----------------------------------------------------------------------------------------------------------

#region Using Directives
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;
using System.ServiceModel.Configuration;
using System.ServiceModel.Channels;
using System.Configuration;
using System.Globalization;

using Microsoft.ServiceModel.Channels.Common;
#endregion

namespace BizTalkFactory.Adapters.AzureStorage
{
    using System;
    using System.Configuration;
    using System.ServiceModel;
    using System.ServiceModel.Channels;
    using System.ServiceModel.Configuration;

    public class AzureStorageAdapterBindingElementExtensionElement : BindingElementExtensionElement
    {
        #region  Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        public AzureStorageAdapterBindingElementExtensionElement()
        {
        }

        #endregion Constructor

        #region Custom Generated Properties

        // General Properties

        // Inbound Properties

        [System.Configuration.ConfigurationProperty("pollingIntervalInSeconds", DefaultValue = 30)]
        public int PollingIntervalInSeconds
        {
            get { return (int)base["pollingIntervalInSeconds"]; }
            set { base["pollingIntervalInSeconds"] = value; }
        }

        [System.Configuration.ConfigurationProperty("pollingStorage", DefaultValue = StorageType.Unspecified)]
        public StorageType PollingStorage
        {
            get { return (StorageType)base["pollingStorage"]; }
            set { base["pollingStorage"] = value; }
        }

        [System.Configuration.ConfigurationProperty("blobMask", DefaultValue = "*.*")]
        public String BlobMask
        {
            get { return (String)base["blobMask"]; }
            set { base["blobMask"] = value; }
        }

        // Local Storage Emulator Connection String Parameters

        [System.Configuration.ConfigurationProperty("developmentStorageProxyUri", DefaultValue = "")]
        public string DevelopmentStorageProxyUri
        {
            get { return (string)base["developmentStorageProxyUri"]; }
            set { base["developmentStorageProxyUri"] = value; }
        }

        // Azure Storage Connection String Parameters

        [System.Configuration.ConfigurationProperty("accountKey", DefaultValue = AzureStorageAdapterConnectionUri.DevelopmentStorageAccountkey)]
        public string AccountKey
        {
            get { return (string)base["accountKey"]; }
            set { base["accountKey"] = value; }
        }

        [System.Configuration.ConfigurationProperty("defaultEndpointsProtocol", DefaultValue = "https")]
        public string DefaultEndpointsProtocol
        {
            get { return (string)base["defaultEndpointsProtocol"]; }
            set { base["defaultEndpointsProtocol"] = value; }
        }

        [System.Configuration.ConfigurationProperty("blobEndpoint", DefaultValue = "")]
        public string BlobEndpoint
        {
            get { return (string)base["blobEndpoint"]; }
            set { base["blobEndpoint"] = value; }
        }

        [System.Configuration.ConfigurationProperty("queueEndpoint", DefaultValue = "")]
        public string QueueEndpoint
        {
            get { return (string)base["QueueEndpoint"]; }
            set { base["QueueEndpoint"] = value; }
        }

        [System.Configuration.ConfigurationProperty("tableEndpoint", DefaultValue = "")]
        public string TableEndpoint
        {
            get { return (string)base["tableEndpoint"]; }
            set { base["tableEndpoint"] = value; }
        }

        [System.Configuration.ConfigurationProperty("sharedAccessSignature", DefaultValue = "")]
        public string SharedAccessSignature
        {
            get { return (string)base["sharedAccessSignature"]; }
            set { base["sharedAccessSignature"] = value; }
        }

        #endregion Custom Generated Properties

        #region BindingElementExtensionElement Methods
        /// <summary>
        /// Return the type of the adapter (binding element)
        /// </summary>
        public override Type BindingElementType
        {
            get
            {
                return typeof(AzureStorageAdapter);
            }
        }
        /// <summary>
        /// Returns a collection of the configuration properties
        /// </summary>
        protected override ConfigurationPropertyCollection Properties
        {
            get
            {
                ConfigurationPropertyCollection configProperties = base.Properties;
                
                // Inbound Properties

                configProperties.Add(new ConfigurationProperty("pollingIntervalInSeconds", typeof(System.Int32), 30, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("pollingStorage", typeof(StorageType), StorageType.Unspecified, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("blobMask", typeof(System.String), "*.*", null, null, ConfigurationPropertyOptions.None));
                
                configProperties.Add(new ConfigurationProperty("developmentStorageProxyUri", typeof(System.String), String.Empty, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("accountKey", typeof(System.String), AzureStorageAdapterConnectionUri.DevelopmentStorageAccountkey, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("defaultEndpointsProtocol", typeof(System.String), "https", null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("blobEndpoint", typeof(System.String), String.Empty, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("queueEndpoint", typeof(System.String), String.Empty, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("tableEndpoint", typeof(System.String), String.Empty, null, null, ConfigurationPropertyOptions.None));
                configProperties.Add(new ConfigurationProperty("sharedAccessSignature", typeof(System.String), String.Empty, null, null, ConfigurationPropertyOptions.None));
                
                return configProperties;
            }
        }

        /// <summary>
        /// Instantiate the adapter.
        /// </summary>
        /// <returns></returns>
        protected override BindingElement CreateBindingElement()
        {
            AzureStorageAdapter adapter = new AzureStorageAdapter();
            this.ApplyConfiguration(adapter);
            return adapter;
        }

        /// <summary>
        /// Apply the configuration properties to the adapter.
        /// </summary>
        /// <param name="bindingElement"></param>
        public override void ApplyConfiguration(BindingElement bindingElement)
        {
            base.ApplyConfiguration(bindingElement);
            AzureStorageAdapter adapterBinding = ((AzureStorageAdapter)(bindingElement));
            
            // General Properties

            // Inbound Properties

            adapterBinding.PollingIntervalInSeconds = (int)this["pollingIntervalInSeconds"];
            adapterBinding.PollingStorage = (StorageType)this["pollingStorage"];
            adapterBinding.BlobMask = (String)this["blobMask"];

            // Development Storage Properties

            adapterBinding.DevelopmentStorageProxyUri = (string)this["developmentStorageProxyUri"];

            // Windows Azure Storage Properties

            adapterBinding.AccountKey = (string)this["accountKey"];
            adapterBinding.DefaultEndpointsProtocol = (string)this["defaultEndpointsProtocol"];
            adapterBinding.BlobEndpoint = (string)this["blobEndpoint"];
            adapterBinding.QueueEndpoint = (string)this["queueEndpoint"];
            adapterBinding.TableEndpoint = (string)this["tableEndpoint"];
            adapterBinding.SharedAccessSignature = (string)this["sharedAccessSignature"];
        }

        /// <summary>
        /// Initialize the binding properties from the adapter.
        /// </summary>
        /// <param name="bindingElement"></param>
        protected override void InitializeFrom(BindingElement bindingElement)
        {
            base.InitializeFrom(bindingElement);
            AzureStorageAdapter adapterBinding = ((AzureStorageAdapter)(bindingElement));

            // General Properties

            // Inbound Properties

            this["pollingIntervalInSeconds"] = adapterBinding.PollingIntervalInSeconds;
            this["pollingStorage"] = adapterBinding.PollingStorage;
            this["blobMask"] = adapterBinding.BlobMask;

            // Development Storage Properties

            this["developmentStorageProxyUri"] = adapterBinding.DevelopmentStorageProxyUri;

            // Windows Azure Storage Properties

            this["accountKey"] = adapterBinding.AccountKey;
            this["defaultEndpointsProtocol"] = adapterBinding.DefaultEndpointsProtocol;
            this["blobEndpoint"] = adapterBinding.BlobEndpoint;
            this["queueEndpoint"] = adapterBinding.QueueEndpoint;
            this["tableEndpoint"] = adapterBinding.TableEndpoint;
            this["sharedAccessSignature"] = adapterBinding.SharedAccessSignature;
        }

        /// <summary>
        /// Copy the properties to the custom binding
        /// </summary>
        /// <param name="from"></param>
        public override void CopyFrom(ServiceModelExtensionElement from)
        {
            base.CopyFrom(from);
            AzureStorageAdapterBindingElementExtensionElement adapterBinding = ((AzureStorageAdapterBindingElementExtensionElement)(from));

            // General Properties

            // Inbound Properties

            this["pollingIntervalInSeconds"] = adapterBinding.PollingIntervalInSeconds;
            this["pollingStorage"] = adapterBinding.PollingStorage;
            this["blobMask"] = adapterBinding.BlobMask;

            // Development Storage Properties

            this["developmentStorageProxyUri"] = adapterBinding.DevelopmentStorageProxyUri;

            // Windows Azure Storage Properties

            this["accountKey"] = adapterBinding.AccountKey;
            this["defaultEndpointsProtocol"] = adapterBinding.DefaultEndpointsProtocol;
            this["blobEndpoint"] = adapterBinding.BlobEndpoint;
            this["queueEndpoint"] = adapterBinding.QueueEndpoint;
            this["tableEndpoint"] = adapterBinding.TableEndpoint;
            this["sharedAccessSignature"] = adapterBinding.SharedAccessSignature;
        }

        #endregion BindingElementExtensionElement Methods
    }
}

